\chapter{Conceptos de Diseño}
En este capítulo se hace una breve introducción a las herramientas de diseño empleadas en el desarrollo del sistema. Comenzando con una introducción a los conceptos de análisis y diseño orientado a objetos, continuando con patrones de diseño y finalmente una breve introducción a UML.
No debería saltearse este capitulo si se desea leer el siguiente, ya que se introducen conceptos importantes de diseño.\\

		
\section{Análisis y Diseño Orientado a Objetos}
El análisis y diseño orientado a objetos es un enfoque de la ingeniería del software que modela un sistema como un grupo de objetos que interactúan entre sí. Cada objeto representa alguna entidad de interés en el sistema que se está modelando, y es caracterizado por una clase, su estado, y su comportamiento. Varios modelos pueden ser creados para mostrar la estructura estática, el comportamiento dinámico, y el despliegue en tiempo de ejecución de estos objetos.
El análisis orientado a objetos (OOA) aplica técnicas de modelado de objetos para analizar los requerimientos funcionales del sistema. El diseño orientado a objetos (OOD) elabora el modelo de análisis para producir especificaciones de implementación. OOA se focaliza en que debe hacer el sistema, OOD en cambio en cómo lo debe hacer.
Para más información se aconseja visitar  \url{http://www.beroux.com/english/articles/oop_uml_and_rup.php}\\


\subsection{Sistema Orientado a Objetos}
Un sistema orientado a objetos está compuesto de objetos. El comportamiento de este sistema resulta de la colaboración de estos objetos donde la interacción involucra el envió de mensajes entre ellos. 

\subsection{Análisis Orientado a Objetos}
El análisis orientado a objetos examina el dominio del problema, con el objetivo de producir un modelo conceptual de la información que existe en el área que esta siendo analizada. El Análisis de los modelos no tienen en cuenta las dificultades de aplicación que puedan existir, tales como la concurrencia, distribución, persistencia, o cómo el sistema se va a construir. Las limitantes de implantación son tratados durante el diseño orientado a objetos (OOD). El análisis se realiza antes que el diseño.
Las fuentes para el análisis puede ser una declaración por escrito de necesidades, un documento formal, entrevistas con las partes interesadas, etc. Un sistema puede ser dividido en varios dominios, que representan diferentes negocios, tecnológicos u otras áreas de interés, cada uno de los cuales se analizan por separado.
El resultado de un análisis orientado a objetos es una descripción de lo que el sistema está funcionalmente obligadas a hacer, en forma de un modelo conceptual. Que típicamente se presenta como un conjunto de casos de uso, uno o más diagramas UML de clases, y una serie de diagramas de interacción. También puede incluir algún tipo de interfaz de usuario. El objetivo de análisis orientado a objetos es desarrollar un modelo que describa los programas informáticos, ya que trabaja para satisfacer un conjunto de requisitos definidos para el cliente.

\subsection{Diseño Orientado a Objetos}
El diseño orientado a objetos transforma el modelo conceptual producido en el análisis orientado a objetos para tener en cuenta las limitaciones impuestas por la arquitectura elegida y cualquier otra limitación de falta de funcionalidad, las limitaciones tecnológicas o medioambientales. Como ser, rendimiento de transacciones, tiempo de respuesta, de ejecución, de tiempo, entorno de desarrollo, o lenguaje de programación.
Los conceptos del modelo de análisis se asignan a clases de implementación y las interfaces. El resultado es un modelo del dominio de solución, una descripción detallada de cómo el sistema se va a construir.


\section{Patrones y Antipatrones de Diseño}

\subsection{Qué son los patrones y antipatrones de diseño}
Los patrones de diseño son la base para la búsqueda de soluciones a problemas comunes en el desarrollo de software y otros ámbitos referentes al diseño de interacción o interfaces.
Un patrón describe un problema que ocurre varias veces en un sistema, y la base de la solución a ese problema.
Los antipatrones de diseño, en cambio, son patrones que invariablemente conducen a una mala solución de un problema.
Tanto los patrones, como los antipatrones de diseño son el resultado del consenso de los profesionales en el área y brindan herramientas a los diseñadores de sistemas para no escoger malos caminos, valiéndose de documentación disponible en lugar de simplemente la intuición.

\subsubsection{Patrones}
Un patrón de diseño es una solución a un problema de diseño. Para que una solución sea considerada un patrón debe poseer ciertas características. Una de ellas es que se debe haber comprobado su efectividad resolviendo problemas similares en ocasiones anteriores. Otra es que debe ser reusable, lo que significa que es aplicable a diferentes problemas de diseño en distintas circunstancias.
Cada patrón de diseño se focaliza sobre un problema o issue particular de diseño (DOO).

En general, un patrón tiene cuatro elementos esenciales:
\begin{enumerate}
	\item \textbf{El nombre del patrón} es un manejador que se usa para describir un problema de diseño, su solución, y consecuencias.
	
	\item \textbf{El problema} describe cuando aplicar el patrón, explica el problema y su contexto. El también describe problemas de diseño especifico tales como \"Como representar un algoritmo como un objeto\". Ademas, describe la estructura de clases y objetos que son sintomáticas de un diseño inflexible. A veces, el problema puede incluir una lista de condiciones que deben ser reunidas antes de que tenga sentido aplicar el patrón. 
	
	\item \textbf{La solución} describe los elementos que integran el diseño, sus relaciones, responsabilidades, y colaboración. La solución no describe un diseño particular concreto o implementación, porque un patrón puede ser aplicado en muchas situaciones diferentes. De hecho, el patrón provee una descripción abstracta de un problema de diseño y como una disposición general de los elementos lo  resuelve.  
	
	\item \textbf{Las consecuencias} son los resultados y compromisos de aplicar el patrón. Estas son fundamentales para evaluar alternativas de diseño y para la comprensión de los costos y beneficios de aplicar el patrón. Las consecuencias de un patrón incluye su impacto sobre la flexibilidad del sistema, expansión, o portabilidad.

\end{enumerate} 

\subsection{Patrones utilizados en el sistema}
A lo largo del proceso de diseño se encontraron problemas que coincidían con patrones. Estos patrones se explican brevemente a continuación: 

\begin{itemize}
	\item Observer: Define una dependencia uno a muchos entre objetos, de forma que si un objeto cambia de estado, todos sus dependientes son notificados y actualizados automáticamente.
	 En la Fig. 4.1 se ve el modelo estándar del patrón.
	 
\begin{figure}[ht]
\centering
\includegraphics[scale=0.8]{pictures/Pattern_Obs.jpg}
\caption{Patrón Observer.} 
\end{figure}

    \textbf{Aplicabilidad} se usa el patrón $Observer$ cuando: 
    \begin{itemize}
    \item Una abstracción tiene dos aspectos, uno dependiente del otro. Encapsular estos aspectos en objetos por separado le permite variarlo y reutilizarlos de manera independiente.
    \item Un cambio de un objeto requiere cambiar a los demás, y no sé sabe cuantos objetos hay que cambiar.
	\item Un objeto debe ser capaz de notificar a otros objetos sin hacer suposiciones acerca de que son estos objetos. En otras palabras, no se quiere que los objetos estén muy acoplados.
    \end{itemize}
    
	\item Adapter: Convierte la interfaz de una clase en otra interfaz que el cliente espera. Los Adapters permiten que trabajen juntas clases que de otra forma no podrían, porque tienen interfaces incompatibles.\\

	Como se ve en la Fig. 4.2, una clase $Adapter$ usa herencia multiple para adaptar una interface a otra. En este caso adapta la interfaz de $SpecificRequest()$ a $Request()$.
	
\begin{figure}[ht]
\centering
\includegraphics[scale=0.8]{pictures/Pattern_Adp.jpg}
\caption{Patrón Adapter.} 
\end{figure}
	
	\textbf{Aplicabilidad} se usa el patrón $Adapter$ cuando:
	\begin{itemize}
	\item Se desea utilizar una clase existente, y su interfaz no coincide con la que se necesita.
	\item Se desea crear una clase reutilizable que coopera con clases no relacionadas o imprevistas, es decir, clases que no tienen necesariamente interfaces compatibles.
	\item ($object\ adapter\ only$) es necesario utilizar varias subclases ya existentes, pero es muy difícil de adaptar sus interfaces por medio de cada subclase. Un adaptador de objeto puede adaptar la interfaz de su clase padre.
	 \end{itemize}
	
	\item Method Factory: Define una interfaz para crear un objeto, pero le permite a las subclases decidir cuales clases instanciar. $Factory Method$ permite aplazar la creación de instancias de una clase a las subclases. \\

	En la Fig. 4.3 se puede ver como se tiene por un lado una interfaz $Product$ que puede tener varias implementaciones y una interfaz $Create$ encargada de producir elementos de tipo $Product$. 
	Ejemplo: supongamos que tenemos una interfaz $Auto$ ($Product$) y dos implementaciones de ella $Auto A$ y $Auto B$, el $Factory Method$ es un método simple que dependiendo del objeto que le pida me va a construir un objeto $Auto A$ o $Auto B$.

\begin{figure}[ht]
\centering
\includegraphics[scale=0.8]{pictures/Pattern_FaM.jpg}
\caption{Patrón Method Factory.} 
\end{figure}

	\textbf{Aplicabilidad} Usar el $Method Factory$	cuando:
	\begin{itemize}
	\item la clase no puede anticipar la clase de objetos que debe crear.
	\item la clase quiere sus subclases para especificar los objetos que crea.
	\item clases delegan la responsabilidad a una de varias subclases ayudantes, y desea saber a cual de las subclases se delego.	
	\end{itemize}	
	
	
	\item Iterator: Proporciona una forma de acceder a los elementos de un objeto agregado de forma secuencial, sin exponer su representación subyacente.
	Como se ve en la Fig. 4.4, tenemos un repositorio $List$ y un iterador que permite acceder al repositorio sin tener conocimiento sobre el mismo.
	
\begin{figure}[ht]
\centering
\includegraphics[scale=0.8]{pictures/Pattern_Ite.jpg}
\caption{Patrón Iterator.} 
\end{figure}	
	
\textbf{Aplicabilidad} Usar el patrón Iterator para:
\begin{itemize}
\item acceder al contenido de un objeto agregado sin exponer su representación interna.
\item apoyar múltiples recorridos de los objetos agregados.
\item proporcionar una interfaz uniforme para recorrer diferentes estructuras agregadas (es decir, para apoyar iteración polimórfica).	
\end{itemize}
	
	\item Template Method: Define el esqueleto de un algoritmo en una operación, derivando algunos pasos a subclases. $Template Method$ permite a subclases redefinir ciertos pasos de un algoritmo sin cambiar la estructura de este.
	En la Fig. 4.5, tenemos un $TemplateMethod()$, que contiene las partes no variables del algoritmo y interfaces para implementar los fragmentos variables del algoritmo($PrimitiveOperationN()$).

\begin{figure}[ht]
\centering
\includegraphics[scale=0.8]{pictures/Pattern_TM.jpg}
\caption{Patrón Template Method.} 
\end{figure}	
	
\textbf{Aplicabilidad} Usar $Template Method$:
\begin{itemize}
\item para implementar las partes invariables de un algoritmo de forma definitiva y dejar a subclases implementar el comportamiento que puede variar.
\item cuando las clases de igual comportamiento deberían ser construidas y localizadas en una clase común para evitar la duplicación de código. 
\item para controlar las extensiones de las subclases.
\end{itemize}
	
\end{itemize}

Para mayor información ver \cite{GOF98} y \cite{GOFANT}
%--------------------------------------------------------------------------------
\section{Principios de Diseño (DOO)}
Dentro de la programación orientada a objetos, existen diferentes principios que ayudan en la elección del modelado de clases, y cómo estas clases deben interactuar.\\

\subsection{SOLID}
SOLID (Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion) es un acrónimo memotécnico introducido por Robert C. Martin a comienzos del 2000 el cual se basa en 5 patrones básicos de diseño y programación orientada a objetos. Cuando los principios se aplican conjuntamente hacen más probable que un programador cree un sistema de fácil mantenimiento y extensible en el tiempo \cite{RoM03}.

\paragraph{Principio de Simple Responsabilidad (SRP)}
En la programación orientada a objetos, el Principio de Simple Responsabilidad, establece que cada objeto debe tener una única responsabilidad, y que la responsabilidad debe ser completamente encapsulado por la clase. Todos sus servicios deben estar estrechamente alineados con esa responsabilidad.

\paragraph{Principio de Apertura/Cierre (OCP)}
El principio de apertura/cierre establece que \"entidades de software (clases, módulos, funciones, etc) debe quedar abierto a la extensión, pero cerrado para su modificación\", es decir, una entidad puede permitir que su comportamiento pueda ser modificado sin alterar su código fuente. 

\paragraph{Principio de sustitución de Liskov (LSP)}
El principio de sustitución de Liskov es una definición particular de una relación de subtipificación, llamado subtipificación de comportamiento, que fue introducido inicialmente por Barbara Liskov. Establece que "los tipos derivados deben poder ser sustitutos completos de sus tipos base".

\paragraph{Principio de Segregación de Interfaz (ISP)}
El principio de interfaz de la segregación dice que una vez que una interfaz se ha puesto demasiado "gorda" tiene que ser dividida en partes más pequeñas y más interfaces específicas para que cualquier cliente de la interfaz pueda sólo saber acerca de los métodos que les pertenecen. En pocas palabras, ningún cliente debería ser obligado a depender de métodos que no utiliza.

\paragraph{Principio de Inversión de Dependencia (DIP)}
El principio de inversión de dependencia promueve que hay que depender de abstracciones, no de concreciones. Dicho de otra forma, los módulos de más alto nivel no deben depender de los de más bajo nivel sino que ambos deben depender de abstracciones. Y a su vez, las abstracciones no deben depender de los detalles sino al contrario.

\section{Tipos de Diseño}
Hay distintas paradigmas de diseño, para el desarrollo de este trabajo tuvimos en cuenta los siguientes:

\begin{itemize}
\item El diseño orientado a datos (Data-driven design) es el resultado de adaptar métodos de diseño de tipos abstractos de datos a la programación orientada a objetos. Las clases se definen en torno a los datos de las estructuras que deben mantenerse.\\

\item El diseño orientado a responsabilidad (Responsibility-driven design) define clases alrededor de los términos de un contrato, es decir, una clase debe ser definida en torno a la responsabilidad y la información que comparte \cite{OOPSLA89}.	
\end{itemize}

Finalmente se optó por el diseño orientado a responsabilidades, este punto se explica detalladamente en el capitulo 5.
